package com.vito.oa.act.action;

import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletResponse;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.util.CellRangeAddress;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.dubbo.config.annotation.Reference;
import com.vito.act.service.ActExApproveInfoService;
import com.vito.base.authoriza.action.BaseAction;
import com.vito.base.authoriza.cache.SessionMap;
import com.vito.base.authoriza.model.FileModel;
import com.vito.base.authoriza.model.UserModel;
import com.vito.base.authoriza.service.DeptService;
import com.vito.base.authoriza.service.UserService;
import com.vito.base.model.ExportExcelModel;
import com.vito.base.model.FtpModel;
import com.vito.base.model.ResMsg;
import com.vito.base.model.Result;
import com.vito.base.util.DateUtils;
import com.vito.base.util.ExportExcelUtil;
import com.vito.base.util.FtpHelper;
import com.vito.base.util.SpringApplicationContext;
import com.vito.base.util.StringUtil;
import com.vito.base.util.Validata;
import com.vito.oa.act.constant.OaActContants;
import com.vito.oa.act.extend.model.OaActExApproveInfoModel;
import com.vito.oa.act.print.PrintInfo;
import com.vito.oa.act.print.PrintInfo.Approval;
import com.vito.oa.act.service.OaActPrintService;

/**
 * 打印
 * @author xzn
 *
 */
@Controller
@RequestMapping("oa/act/print")
public class OaActPrinitAction extends BaseAction{
	private static final Logger log = LoggerFactory.getLogger(OaActPrinitAction.class);

	@Reference
	private UserService userServiceImpl;

	@Reference
	private DeptService deptServiceImpl;
	
	@Reference
	private OaActPrintService oaActPrintService;
	@Reference
	private ActExApproveInfoService actExApproveInfoService;

	@ResponseBody
	@RequestMapping(value = "printprocess")
	public Result printProcess(String businessId) {
		Result rs = new Result();
		PrintInfo printInfo = new PrintInfo();
		try {
			UserModel printUser = SessionMap.getObj();
			if (null == printUser) {
				rs.setCode(Result.CODE_LOGIN_REQUIRE);
				rs.setMsg(ResMsg.MSG_LOGIN_NEED);
				return rs;
			}
			//获取审批流程基本信息
			OaActExApproveInfoModel processInfo = oaActPrintService.queryProcessInfo(businessId);
			//封装审批数据
			printInfo= oaActPrintService.getInfoPdf(processInfo);
			String processName =printInfo.getProcessName();
			printInfo.setTitle(processName);
			printInfo.setPrintPersion(printUser.getUserName());
			printInfo.setCompanyName(printUser.getDeptParentName());
			printInfo.setPrintTime(DateUtils.formatToStr(new Date(), "yyyy-MM-dd HH:mm"));
			String fileName = printInfo.getStartUser()+"的"+processName+"申请";
			printInfo.setFileName(fileName);
			
			//pdf文件构造并上传至ftp
			FileModel model = oaActPrintService.printProcess(printInfo);					
			rs.setCode(Result.CODE_OK);
			rs.setData(model);	
			rs.setMsg("系统已为您生成pdf格式文件，确定下载？");
		} catch (Exception e) {
			log.error("执行异常", e);
			rs.setCode(Result.CODE_ERROR);
			rs.setMsg(ResMsg.EXECERR);
		}
		return rs;
	}
	
	@RequestMapping("processDownload")
	@ResponseBody
	public Result processDownload(String filePath){
		Result rs = new Result();
		try{
			if(!StringUtil.isEmpty(filePath)){
				String path = filePath.substring(filePath.lastIndexOf("/")+1);
				path = path.substring(0,path.lastIndexOf("__"))+"_";
				path = "/"+path.replaceAll("_", "/");
				String newName = filePath.substring(filePath.lastIndexOf("__")+1);		
				FtpModel ftpModel = new FtpModel();
				ftpModel.setFileNewName(newName);
				ftpModel.setFilePath(path);		

				new FtpHelper().download(ftpModel, SpringApplicationContext.getRequest(),SpringApplicationContext.getResponse());
			}else{
				rs.setCode(Result.CODE_PARA_ERROR);
				rs.setMsg("文件路径不能为空");
			}
		}catch(Exception e){
			log.error("执行异常", e);
			rs.setCode(Result.CODE_ERROR);
			rs.setMsg(ResMsg.EXECERR);
		}
		return null;
	}
	
	@SuppressWarnings("unchecked")
	@RequestMapping("exportExcel")
	@ResponseBody
	public Result exportApproveByExcel(OaActExApproveInfoModel actExApproveInfoModel,HttpServletResponse response){
		Result rs = new Result();
		List<PrintInfo> exportList = new ArrayList<PrintInfo>();
		BufferedOutputStream out=null;
		UserModel user = SessionMap.getObj();
		if(user == null || Validata.isNullOrEmpty(user.getUserId())){
			rs.setCode(Result.CODE_LOGIN_REQUIRE);
			rs.setMsg(ResMsg.MSG_LOGIN_NEED);
			return rs;
		}
		if(!Validata.isNullOrEmpty(actExApproveInfoModel.getEndtime())){
			SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
			try {
				actExApproveInfoModel.setEndtime(df.format(df.parse(actExApproveInfoModel.getEndtime()))+" 23:59:59");
			} catch (ParseException e) {
				e.printStackTrace();
			}
		}
		actExApproveInfoModel.setCreateDept(user.getDeptParentId());
		actExApproveInfoModel.setDataStatus(OaActContants.PROCESS_DATA_STATUS_CONMON);
		List<OaActExApproveInfoModel> processInfos = oaActPrintService.queryProcessInfo(actExApproveInfoModel);
		
		List<PrintInfo> printList = oaActPrintService.getInfoExcel(processInfos);
		Collections.sort(printList);
		for(PrintInfo info : printList){
			if(info == null){
				continue;
			}
			LinkedHashMap<String, String> allInfoMap = new LinkedHashMap<String, String>();
			allInfoMap.put("审批类型", info.getProcessName());
			allInfoMap.put("审批状态", info.getStatusText());
			allInfoMap.put("申请人",info.getStartUser());
			allInfoMap.put("申请人部门",info.getStartUserDept());
			allInfoMap.put("发起时间",info.getStartTime());
			allInfoMap.put("完成时间", info.getEndTime());							
			
			StringBuilder approvalStr = new StringBuilder().append("");
			ArrayList<Approval> approvalList = info.getApprovalInfo();
			for(Approval approver: approvalList){
				approvalStr.append(approver.toString()+"\r\n");
			}
			if(Validata.isNullOrEmpty(approvalStr.toString())){
				allInfoMap.put("审批记录", "无审批信息");
			}else{
				allInfoMap.put("审批记录", approvalStr.substring(0, approvalStr.lastIndexOf("\r\n")).toString());
			}
			Map<String, Object> main = info.getMainForm();
			if(main == null || main.isEmpty()){
				continue;
			}
			allInfoMap.putAll((LinkedHashMap<String,String>)main.get("main"));
			info.getMainForm().put("main",allInfoMap);				
			exportList.add(info);
		}
		if(!exportList.isEmpty()){
			//表头数据
		    List<String> headerList = new ArrayList<String>();
		    
		    PrintInfo data_0 = exportList.get(0);
		    Map<String,Object> form_0 = data_0.getMainForm();
		    LinkedHashMap<String,String> main_0 = (LinkedHashMap<String,String>)form_0.get("main"); 
		    List<Map<String,String>> subs_0 = (List<Map<String,String>>)form_0.get("sub");
		    
		    for(String mainHeader : main_0.keySet()){
		    	headerList.add(mainHeader);
		    }
		    if(subs_0 != null && subs_0.size() > 0){
    			Map<String,String> sub_0 = subs_0.get(0); 
			    for(String subHeader : sub_0.keySet()){
			    	headerList.add(subHeader);			    	
			    }		    	
		    }
		    
		    //主体数据
		    List<Map<String,String>> allData = new ArrayList<Map<String,String>>();
		    for(PrintInfo data : exportList){
		    	 Map<String,Object> item = data.getMainForm();
		    	 LinkedHashMap<String,String> main_item= (LinkedHashMap<String,String>)item.get("main");
			    List<Map<String,String>> subs_item = (List<Map<String,String>>)item.get("sub");
		    	if(subs_item != null && subs_item.size() > 0){
		    		for(Map<String,String> sub : subs_item){
		    			sub.putAll(main_item);
		    			allData.add(sub);
		    		}
		    	}else{
		    		allData.add(main_item);
		    	}
		    }
	/*******************************创建表Start********************************************/
		    HSSFWorkbook wb = new HSSFWorkbook();	
			ExportExcelUtil excelUtil = new ExportExcelUtil();
			ExportExcelModel excelModel = new ExportExcelModel();
			excelModel.setCreateTime(DateUtils.formatToStr(new Date(), "yyyy-MM-dd HH:mm"));
			excelModel.setCreator(user.getUserName());
			excelModel.setFontSize(11);
		  
		    HSSFSheet sheet = wb.createSheet(DateUtils.getDefaultDate());
		    int index = 0;//行索引
		    int len = headerList.size();
		    HSSFCellStyle styleTitle =  excelUtil.setExcleTitleStyle(wb, excelModel, true);
		    HSSFCellStyle styleHeader = excelUtil.setExcleTitleStyle(wb, excelModel, false);
		    //标题
		    HSSFRow rowTitle = sheet.createRow(index);
		    rowTitle.setHeight((short)400);
		    HSSFCell cellTitle= rowTitle.createCell(0);
		    styleTitle.setAlignment(HSSFCellStyle.ALIGN_LEFT);
		    cellTitle.setCellStyle(styleTitle);
		    cellTitle.setCellValue("导出人："+excelModel.getCreator()+"  导出时间：" + excelModel.getCreateTime());
		    sheet.addMergedRegion(new CellRangeAddress(0,0,0,len-1));
		    index++;
		    //表头
		    //[审批类型，申请人，部门，状态，发起时间，结束时间，审批记录，...动态内容...]
		    HSSFRow rowHeader = sheet.createRow(index);
		    rowHeader.setHeight((short)400);
		    for(int i=0;i<len;i++){
		    	HSSFCell cell = rowHeader.createCell(i);
		    	if(i == headerList.indexOf("申请人部门")){
		    		sheet.setColumnWidth(i, 7000);
		    	}else if(i==headerList.indexOf("审批记录")){
		    		sheet.setColumnWidth(i, 10000);
		    	}else if(i>headerList.indexOf("审批记录")){
		    		sheet.setColumnWidth(i, 8000);
		    	}else{
		    		sheet.setColumnWidth(i, 5000);
		    	}
		    	styleHeader.setAlignment(HSSFCellStyle.ALIGN_CENTER);
	            cell.setCellStyle(styleHeader);
	            cell.setCellValue(headerList.get(i));
		    }
		    index++;
		    //主体
		    boolean flag = true;
		    for(Map<String,String> row : allData){
			    HSSFCellStyle styleRow = excelUtil.setExcleRowStyle(wb, excelModel, flag);
			    styleRow.setWrapText(true); 
			    styleRow.setAlignment(HSSFCellStyle.ALIGN_CENTER);
			    styleRow.setFillForegroundColor(HSSFColor.WHITE.index);
		    	HSSFRow  row_item = sheet.createRow(index);
		    	for(int j=0; j<headerList.size();j++){
		    		HSSFCell cell_item = row_item.createCell(j);
		    		cell_item.setCellStyle(styleRow);
		    		String value = row.get(headerList.get(j));
		    		if(value != null && value.length()>0){
			    		 Pattern p = Pattern.compile("^(-?\\d+)(\\.\\d+)?$");  
			             Matcher matcher = p.matcher(value); 
			             if (matcher.matches()){  
			                 // 是数字当作double处理  
			            	 cell_item.setCellValue(Double.parseDouble(value));  
			             }else {  
			                 cell_item.setCellValue(new HSSFRichTextString(value));  
			             }
		    		}else{
		    			cell_item.setCellValue("");
		    		}
		    	}
		    	flag = !flag;
		    	index++;
		    }
	/*************************************创建表End*****************************************************/	    
		    response.reset();
			response.setContentType("application/x-download");
			try {
				response.setHeader("Content-Disposition","attachment;filename="+ new String((excelModel.getCreateTime()+".xls").getBytes("gb2312"),"ISO8859-1"));
				response.setHeader("Pragma", "No-cache");  
				response.setHeader("Cache-Control", "No-cache");  
				response.setDateHeader("Expires", 0);
				out = new BufferedOutputStream(response.getOutputStream(),256); 	
				wb.write(out);
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}finally{
				if(out != null){
					try {
						out.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			}
		}	    
	
		return null;
	}
}
